{
  "nbformat": 4,
  "nbformat_minor": 0,
  "metadata": {
    "colab": {
      "name": "NeuralNet.ipynb",
      "provenance": [],
      "collapsed_sections": [],
      "machine_shape": "hm"
    },
    "kernelspec": {
      "name": "python3",
      "display_name": "Python 3"
    },
    "accelerator": "TPU"
  },
  "cells": [
    {
      "cell_type": "code",
      "metadata": {
        "id": "28JCZXo2qPQe",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "from __future__ import absolute_import, division, print_function, unicode_literals\n",
        "\n",
        "import numpy as np\n",
        "import pandas as pd\n",
        "\n",
        "import tensorflow as tf\n",
        "\n",
        "from tensorflow import feature_column\n",
        "from tensorflow.keras import layers\n",
        "from sklearn.model_selection import train_test_split\n",
        "from sklearn.preprocessing import LabelEncoder,OneHotEncoder\n",
        "from sklearn.metrics import classification_report,confusion_matrix"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "uV6KoDWB1E0U",
        "colab_type": "code",
        "outputId": "ae4e4588-c360-4b2a-bdc9-3de10ace9cab",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 124
        }
      },
      "source": [
        "from google.colab import drive \n",
        "drive.mount('/content/gdrive')"
      ],
      "execution_count": 2,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "Go to this URL in a browser: https://accounts.google.com/o/oauth2/auth?client_id=947318989803-6bn6qk8qdgf4n4g3pfee6491hc0brc4i.apps.googleusercontent.com&redirect_uri=urn%3Aietf%3Awg%3Aoauth%3A2.0%3Aoob&scope=email%20https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fdocs.test%20https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fdrive%20https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fdrive.photos.readonly%20https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fpeopleapi.readonly&response_type=code\n",
            "\n",
            "Enter your authorization code:\n",
            "··········\n",
            "Mounted at /content/gdrive\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "WfFAIHKS2xxO",
        "colab_type": "code",
        "outputId": "637023a0-4651-4f4e-958f-8a1553c8dc33",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 261
        }
      },
      "source": [
        "import pandas as pd \n",
        "\n",
        "# Feature names from the file kddcup.names file to be used as cols heading\n",
        "col_names = [\"duration\",\"protocol_type\",\"service\",\"flag\",\"src_bytes\",\n",
        "    \"dst_bytes\",\"land\",\"wrong_fragment\",\"urgent\",\"hot\",\"num_failed_logins\",\n",
        "    \"logged_in\",\"num_compromised\",\"root_shell\",\"su_attempted\",\"num_root\",\n",
        "    \"num_file_creations\",\"num_shells\",\"num_access_files\",\"num_outbound_cmds\",\n",
        "    \"is_host_login\",\"is_guest_login\",\"count\",\"srv_count\",\"serror_rate\",\n",
        "    \"srv_serror_rate\",\"rerror_rate\",\"srv_rerror_rate\",\"same_srv_rate\",\n",
        "    \"diff_srv_rate\",\"srv_diff_host_rate\",\"dst_host_count\",\"dst_host_srv_count\",\n",
        "    \"dst_host_same_srv_rate\",\"dst_host_diff_srv_rate\",\"dst_host_same_src_port_rate\",\n",
        "    \"dst_host_srv_diff_host_rate\",\"dst_host_serror_rate\",\"dst_host_srv_serror_rate\",\n",
        "    \"dst_host_rerror_rate\",\"dst_host_srv_rerror_rate\",\"label\"]\n",
        "\n",
        "df = pd.read_csv(\"/content/gdrive/My Drive/data/df_train.csv\", header=None, names = col_names)\n",
        "\n",
        "# df=pd.read_csv('/content/gdrive/My Drive/data/kddcup.data_10_percent_corrected')\n",
        "df.head()"
      ],
      "execution_count": 3,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "/usr/local/lib/python3.6/dist-packages/IPython/core/interactiveshell.py:2718: DtypeWarning: Columns (0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41) have mixed types. Specify dtype option on import or set low_memory=False.\n",
            "  interactivity=interactivity, compiler=compiler, result=result)\n"
          ],
          "name": "stderr"
        },
        {
          "output_type": "execute_result",
          "data": {
            "text/html": [
              "<div>\n",
              "<style scoped>\n",
              "    .dataframe tbody tr th:only-of-type {\n",
              "        vertical-align: middle;\n",
              "    }\n",
              "\n",
              "    .dataframe tbody tr th {\n",
              "        vertical-align: top;\n",
              "    }\n",
              "\n",
              "    .dataframe thead th {\n",
              "        text-align: right;\n",
              "    }\n",
              "</style>\n",
              "<table border=\"1\" class=\"dataframe\">\n",
              "  <thead>\n",
              "    <tr style=\"text-align: right;\">\n",
              "      <th></th>\n",
              "      <th>duration</th>\n",
              "      <th>protocol_type</th>\n",
              "      <th>service</th>\n",
              "      <th>flag</th>\n",
              "      <th>src_bytes</th>\n",
              "      <th>dst_bytes</th>\n",
              "      <th>land</th>\n",
              "      <th>wrong_fragment</th>\n",
              "      <th>urgent</th>\n",
              "      <th>hot</th>\n",
              "      <th>num_failed_logins</th>\n",
              "      <th>logged_in</th>\n",
              "      <th>num_compromised</th>\n",
              "      <th>root_shell</th>\n",
              "      <th>su_attempted</th>\n",
              "      <th>num_root</th>\n",
              "      <th>num_file_creations</th>\n",
              "      <th>num_shells</th>\n",
              "      <th>num_access_files</th>\n",
              "      <th>num_outbound_cmds</th>\n",
              "      <th>is_host_login</th>\n",
              "      <th>is_guest_login</th>\n",
              "      <th>count</th>\n",
              "      <th>srv_count</th>\n",
              "      <th>serror_rate</th>\n",
              "      <th>srv_serror_rate</th>\n",
              "      <th>rerror_rate</th>\n",
              "      <th>srv_rerror_rate</th>\n",
              "      <th>same_srv_rate</th>\n",
              "      <th>diff_srv_rate</th>\n",
              "      <th>srv_diff_host_rate</th>\n",
              "      <th>dst_host_count</th>\n",
              "      <th>dst_host_srv_count</th>\n",
              "      <th>dst_host_same_srv_rate</th>\n",
              "      <th>dst_host_diff_srv_rate</th>\n",
              "      <th>dst_host_same_src_port_rate</th>\n",
              "      <th>dst_host_srv_diff_host_rate</th>\n",
              "      <th>dst_host_serror_rate</th>\n",
              "      <th>dst_host_srv_serror_rate</th>\n",
              "      <th>dst_host_rerror_rate</th>\n",
              "      <th>dst_host_srv_rerror_rate</th>\n",
              "      <th>label</th>\n",
              "    </tr>\n",
              "  </thead>\n",
              "  <tbody>\n",
              "    <tr>\n",
              "      <th>0</th>\n",
              "      <td>duration</td>\n",
              "      <td>protocol_type</td>\n",
              "      <td>service</td>\n",
              "      <td>flag</td>\n",
              "      <td>src_bytes</td>\n",
              "      <td>dst_bytes</td>\n",
              "      <td>land</td>\n",
              "      <td>wrong_fragment</td>\n",
              "      <td>urgent</td>\n",
              "      <td>hot</td>\n",
              "      <td>num_failed_logins</td>\n",
              "      <td>logged_in</td>\n",
              "      <td>num_compromised</td>\n",
              "      <td>root_shell</td>\n",
              "      <td>su_attempted</td>\n",
              "      <td>num_root</td>\n",
              "      <td>num_file_creations</td>\n",
              "      <td>num_shells</td>\n",
              "      <td>num_access_files</td>\n",
              "      <td>num_outbound_cmds</td>\n",
              "      <td>is_host_login</td>\n",
              "      <td>is_guest_login</td>\n",
              "      <td>count</td>\n",
              "      <td>srv_count</td>\n",
              "      <td>serror_rate</td>\n",
              "      <td>srv_serror_rate</td>\n",
              "      <td>rerror_rate</td>\n",
              "      <td>srv_rerror_rate</td>\n",
              "      <td>same_srv_rate</td>\n",
              "      <td>diff_srv_rate</td>\n",
              "      <td>srv_diff_host_rate</td>\n",
              "      <td>dst_host_count</td>\n",
              "      <td>dst_host_srv_count</td>\n",
              "      <td>dst_host_same_srv_rate</td>\n",
              "      <td>dst_host_diff_srv_rate</td>\n",
              "      <td>dst_host_same_src_port_rate</td>\n",
              "      <td>dst_host_srv_diff_host_rate</td>\n",
              "      <td>dst_host_serror_rate</td>\n",
              "      <td>dst_host_srv_serror_rate</td>\n",
              "      <td>dst_host_rerror_rate</td>\n",
              "      <td>dst_host_srv_rerror_rate</td>\n",
              "      <td>label</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>1</th>\n",
              "      <td>0</td>\n",
              "      <td>1</td>\n",
              "      <td>49</td>\n",
              "      <td>5</td>\n",
              "      <td>0</td>\n",
              "      <td>0</td>\n",
              "      <td>0</td>\n",
              "      <td>0</td>\n",
              "      <td>0</td>\n",
              "      <td>0</td>\n",
              "      <td>0</td>\n",
              "      <td>0</td>\n",
              "      <td>0</td>\n",
              "      <td>0</td>\n",
              "      <td>0</td>\n",
              "      <td>0</td>\n",
              "      <td>0</td>\n",
              "      <td>0</td>\n",
              "      <td>0</td>\n",
              "      <td>0</td>\n",
              "      <td>0</td>\n",
              "      <td>0</td>\n",
              "      <td>296</td>\n",
              "      <td>11</td>\n",
              "      <td>1.0</td>\n",
              "      <td>1.0</td>\n",
              "      <td>0.0</td>\n",
              "      <td>0.0</td>\n",
              "      <td>0.04</td>\n",
              "      <td>0.05</td>\n",
              "      <td>0.0</td>\n",
              "      <td>255</td>\n",
              "      <td>11</td>\n",
              "      <td>0.04</td>\n",
              "      <td>0.05</td>\n",
              "      <td>0.0</td>\n",
              "      <td>0.0</td>\n",
              "      <td>1.0</td>\n",
              "      <td>1.0</td>\n",
              "      <td>0.0</td>\n",
              "      <td>0.0</td>\n",
              "      <td>1</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>2</th>\n",
              "      <td>22</td>\n",
              "      <td>2</td>\n",
              "      <td>49</td>\n",
              "      <td>9</td>\n",
              "      <td>105</td>\n",
              "      <td>147</td>\n",
              "      <td>0</td>\n",
              "      <td>0</td>\n",
              "      <td>0</td>\n",
              "      <td>0</td>\n",
              "      <td>0</td>\n",
              "      <td>0</td>\n",
              "      <td>0</td>\n",
              "      <td>0</td>\n",
              "      <td>0</td>\n",
              "      <td>0</td>\n",
              "      <td>0</td>\n",
              "      <td>0</td>\n",
              "      <td>0</td>\n",
              "      <td>0</td>\n",
              "      <td>0</td>\n",
              "      <td>0</td>\n",
              "      <td>2</td>\n",
              "      <td>2</td>\n",
              "      <td>0.0</td>\n",
              "      <td>0.0</td>\n",
              "      <td>0.0</td>\n",
              "      <td>0.0</td>\n",
              "      <td>1.0</td>\n",
              "      <td>0.0</td>\n",
              "      <td>0.0</td>\n",
              "      <td>255</td>\n",
              "      <td>235</td>\n",
              "      <td>0.92</td>\n",
              "      <td>0.01</td>\n",
              "      <td>0.01</td>\n",
              "      <td>0.0</td>\n",
              "      <td>0.0</td>\n",
              "      <td>0.0</td>\n",
              "      <td>0.0</td>\n",
              "      <td>0.0</td>\n",
              "      <td>0</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>3</th>\n",
              "      <td>0</td>\n",
              "      <td>1</td>\n",
              "      <td>20</td>\n",
              "      <td>9</td>\n",
              "      <td>383</td>\n",
              "      <td>0</td>\n",
              "      <td>0</td>\n",
              "      <td>0</td>\n",
              "      <td>0</td>\n",
              "      <td>0</td>\n",
              "      <td>0</td>\n",
              "      <td>0</td>\n",
              "      <td>0</td>\n",
              "      <td>0</td>\n",
              "      <td>0</td>\n",
              "      <td>0</td>\n",
              "      <td>0</td>\n",
              "      <td>0</td>\n",
              "      <td>0</td>\n",
              "      <td>0</td>\n",
              "      <td>0</td>\n",
              "      <td>0</td>\n",
              "      <td>1</td>\n",
              "      <td>14</td>\n",
              "      <td>0.0</td>\n",
              "      <td>0.0</td>\n",
              "      <td>0.0</td>\n",
              "      <td>0.0</td>\n",
              "      <td>1.0</td>\n",
              "      <td>0.0</td>\n",
              "      <td>0.14</td>\n",
              "      <td>200</td>\n",
              "      <td>94</td>\n",
              "      <td>0.38</td>\n",
              "      <td>0.03</td>\n",
              "      <td>0.38</td>\n",
              "      <td>0.02</td>\n",
              "      <td>0.0</td>\n",
              "      <td>0.0</td>\n",
              "      <td>0.0</td>\n",
              "      <td>0.0</td>\n",
              "      <td>0</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>4</th>\n",
              "      <td>0</td>\n",
              "      <td>1</td>\n",
              "      <td>49</td>\n",
              "      <td>5</td>\n",
              "      <td>0</td>\n",
              "      <td>0</td>\n",
              "      <td>0</td>\n",
              "      <td>0</td>\n",
              "      <td>0</td>\n",
              "      <td>0</td>\n",
              "      <td>0</td>\n",
              "      <td>0</td>\n",
              "      <td>0</td>\n",
              "      <td>0</td>\n",
              "      <td>0</td>\n",
              "      <td>0</td>\n",
              "      <td>0</td>\n",
              "      <td>0</td>\n",
              "      <td>0</td>\n",
              "      <td>0</td>\n",
              "      <td>0</td>\n",
              "      <td>0</td>\n",
              "      <td>232</td>\n",
              "      <td>9</td>\n",
              "      <td>1.0</td>\n",
              "      <td>1.0</td>\n",
              "      <td>0.0</td>\n",
              "      <td>0.0</td>\n",
              "      <td>0.04</td>\n",
              "      <td>0.06</td>\n",
              "      <td>0.0</td>\n",
              "      <td>255</td>\n",
              "      <td>9</td>\n",
              "      <td>0.04</td>\n",
              "      <td>0.07</td>\n",
              "      <td>0.0</td>\n",
              "      <td>0.0</td>\n",
              "      <td>1.0</td>\n",
              "      <td>1.0</td>\n",
              "      <td>0.0</td>\n",
              "      <td>0.0</td>\n",
              "      <td>1</td>\n",
              "    </tr>\n",
              "  </tbody>\n",
              "</table>\n",
              "</div>"
            ],
            "text/plain": [
              "   duration  protocol_type  ...  dst_host_srv_rerror_rate  label\n",
              "0  duration  protocol_type  ...  dst_host_srv_rerror_rate  label\n",
              "1         0              1  ...                       0.0      1\n",
              "2        22              2  ...                       0.0      0\n",
              "3         0              1  ...                       0.0      0\n",
              "4         0              1  ...                       0.0      1\n",
              "\n",
              "[5 rows x 42 columns]"
            ]
          },
          "metadata": {
            "tags": []
          },
          "execution_count": 3
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "9yZoa8rvLuEa",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "## Data Preperation for training\n",
        "# ------------------------------\n",
        "def prepare_data(df):\n",
        "  '''This function prepares the dataset for training. \n",
        "  All categorical data will be encoded using LabelEncoder() of Sklearn. \n",
        "  Labels of each sample will be encoded into five categories as follows: -\n",
        "  \n",
        "    0 - Normal connection\n",
        "    1 - dos attack\n",
        "    2 - probe attack\n",
        "    3 - r2l attack\n",
        "    4 - u2r attack\n",
        "  '''\n",
        "  # Encoding the categorical label to five categories:\n",
        "  newlabeldf=df['label'].replace({ 'normal.' : 0, 'neptune.' : 1 ,'back.': 1, 'land.': 1, 'pod.': 1, 'smurf.': 1, 'teardrop.': 1,'mailbomb.': 1, 'apache2.': 1, 'processtable.': 1, 'udpstorm.': 1, 'worm.': 1,\n",
        "                           'ipsweep.' : 2,'nmap.' : 2,'portsweep.' : 2,'satan.' : 2,'mscan.' : 2,'saint.' : 2\n",
        "                           ,'ftp_write.': 3,'guess_passwd.': 3,'imap.': 3,'multihop.': 3,'phf.': 3,'spy.': 3,'warezclient.': 3,'warezmaster.': 3,'sendmail.': 3,'named.': 3,'snmpgetattack.': 3,'snmpguess.': 3,'xlock.': 3,'xsnoop.': 3,'httptunnel.': 3,\n",
        "                           'buffer_overflow.': 4,'loadmodule.': 4,'perl.': 4,'rootkit.': 4,'ps.': 4,'sqlattack.': 4,'xterm.': 4})\n",
        "  df['label'] = newlabeldf.astype('int')\n",
        "  \n",
        "  # Encoding categorical data using LabelEncoder()\n",
        "  le = LabelEncoder()\n",
        "  df['protocol_type'] = le.fit_transform(df['protocol_type'])\n",
        "  df['service']= le.fit_transform(df['service'])\n",
        "  df['flag'] = le.fit_transform(df['flag'])\n",
        "  \n",
        "  return df\n",
        "  "
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "grxlSUbpp7R1",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "# X = df.iloc[:,:41]\n",
        "# y = df.iloc[:,-1].astype('int')\n"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "wwEJLsMBTHVM",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "df = prepare_data(df)"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "e8QINkS4spWf",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "df_train, df_test = train_test_split(df, stratify=df['label'], test_size=0.25)\n",
        "df_train, df_val = train_test_split(df_train, stratify=df_train['label'], test_size=0.3333)\n",
        "\n"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "WzFrfctiMCZc",
        "colab_type": "code",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 219
        },
        "outputId": "52d297ea-e340-4c84-e04e-04e1a5448b85"
      },
      "source": [
        "df_train.to_csv('df_train.csv', index=False)\n",
        "df_val.to_csv('df_val.csv', index=False)\n",
        "df_test.to_csv('df_test.csv', index=False)\n",
        "\n"
      ],
      "execution_count": 4,
      "outputs": [
        {
          "output_type": "error",
          "ename": "NameError",
          "evalue": "ignored",
          "traceback": [
            "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
            "\u001b[0;31mNameError\u001b[0m                                 Traceback (most recent call last)",
            "\u001b[0;32m<ipython-input-4-d74ee1ae81fa>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mdf_train\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mto_csv\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'df_train.csv'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mindex\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mFalse\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m      2\u001b[0m \u001b[0mdf_val\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mto_csv\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'df_val.csv'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mindex\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mFalse\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m      3\u001b[0m \u001b[0mdf_test\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mto_csv\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'df_test.csv'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mindex\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mFalse\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m      4\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n",
            "\u001b[0;31mNameError\u001b[0m: name 'df_train' is not defined"
          ]
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "s0MEvkAjfglo",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "!cp df_train.csv /content/gdrive/My\\ Drive/data/df_train.csv"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "FjWvxn7bgTyQ",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "!cp df_val.csv /content/gdrive/My\\ Drive/data/df_val.csv"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "sIAOgn2igUoj",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "!cp df_test.csv /content/gdrive/My\\ Drive/data/df_test.csv"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "l0uviy0bMb0o",
        "colab_type": "text"
      },
      "source": [
        "## Visualizing the catogaries (normal + four attack types)"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "WaoDh6iTL4f3",
        "colab_type": "code",
        "outputId": "7bb98647-1695-40cb-d963-1e92a624f194",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 226
        }
      },
      "source": [
        "from numpy import where\n",
        "from matplotlib import pyplot as plt\n",
        "from sklearn.decomposition import PCA\n",
        "from sklearn.preprocessing import StandardScaler\n",
        "\n",
        "X = df.iloc[:,:41]\n",
        "X = StandardScaler().fit_transform(X)\n",
        "y = df.iloc[:,-1].astype('int')\n",
        "\n",
        "pd.DataFrame(data = X, columns = col_names[:-1]).head()"
      ],
      "execution_count": 0,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/html": [
              "<div>\n",
              "<style scoped>\n",
              "    .dataframe tbody tr th:only-of-type {\n",
              "        vertical-align: middle;\n",
              "    }\n",
              "\n",
              "    .dataframe tbody tr th {\n",
              "        vertical-align: top;\n",
              "    }\n",
              "\n",
              "    .dataframe thead th {\n",
              "        text-align: right;\n",
              "    }\n",
              "</style>\n",
              "<table border=\"1\" class=\"dataframe\">\n",
              "  <thead>\n",
              "    <tr style=\"text-align: right;\">\n",
              "      <th></th>\n",
              "      <th>duration</th>\n",
              "      <th>protocol_type</th>\n",
              "      <th>service</th>\n",
              "      <th>flag</th>\n",
              "      <th>src_bytes</th>\n",
              "      <th>dst_bytes</th>\n",
              "      <th>land</th>\n",
              "      <th>wrong_fragment</th>\n",
              "      <th>urgent</th>\n",
              "      <th>hot</th>\n",
              "      <th>num_failed_logins</th>\n",
              "      <th>logged_in</th>\n",
              "      <th>num_compromised</th>\n",
              "      <th>root_shell</th>\n",
              "      <th>su_attempted</th>\n",
              "      <th>num_root</th>\n",
              "      <th>num_file_creations</th>\n",
              "      <th>num_shells</th>\n",
              "      <th>num_access_files</th>\n",
              "      <th>num_outbound_cmds</th>\n",
              "      <th>is_host_login</th>\n",
              "      <th>is_guest_login</th>\n",
              "      <th>count</th>\n",
              "      <th>srv_count</th>\n",
              "      <th>serror_rate</th>\n",
              "      <th>srv_serror_rate</th>\n",
              "      <th>rerror_rate</th>\n",
              "      <th>srv_rerror_rate</th>\n",
              "      <th>same_srv_rate</th>\n",
              "      <th>diff_srv_rate</th>\n",
              "      <th>srv_diff_host_rate</th>\n",
              "      <th>dst_host_count</th>\n",
              "      <th>dst_host_srv_count</th>\n",
              "      <th>dst_host_same_srv_rate</th>\n",
              "      <th>dst_host_diff_srv_rate</th>\n",
              "      <th>dst_host_same_src_port_rate</th>\n",
              "      <th>dst_host_srv_diff_host_rate</th>\n",
              "      <th>dst_host_serror_rate</th>\n",
              "      <th>dst_host_srv_serror_rate</th>\n",
              "      <th>dst_host_rerror_rate</th>\n",
              "      <th>dst_host_srv_rerror_rate</th>\n",
              "    </tr>\n",
              "  </thead>\n",
              "  <tbody>\n",
              "    <tr>\n",
              "      <th>0</th>\n",
              "      <td>-0.067792</td>\n",
              "      <td>0.925753</td>\n",
              "      <td>-0.104067</td>\n",
              "      <td>0.514274</td>\n",
              "      <td>-0.002879</td>\n",
              "      <td>0.138664</td>\n",
              "      <td>-0.006673</td>\n",
              "      <td>-0.04772</td>\n",
              "      <td>-0.002571</td>\n",
              "      <td>-0.044136</td>\n",
              "      <td>-0.009782</td>\n",
              "      <td>2.39698</td>\n",
              "      <td>-0.005679</td>\n",
              "      <td>-0.010552</td>\n",
              "      <td>-0.004676</td>\n",
              "      <td>-0.00564</td>\n",
              "      <td>-0.011232</td>\n",
              "      <td>-0.009919</td>\n",
              "      <td>-0.027632</td>\n",
              "      <td>0.0</td>\n",
              "      <td>0.0</td>\n",
              "      <td>-0.037263</td>\n",
              "      <td>-1.521417</td>\n",
              "      <td>-1.15664</td>\n",
              "      <td>-0.46409</td>\n",
              "      <td>-0.46352</td>\n",
              "      <td>-0.24796</td>\n",
              "      <td>-0.248631</td>\n",
              "      <td>0.536987</td>\n",
              "      <td>-0.255243</td>\n",
              "      <td>-0.203633</td>\n",
              "      <td>-3.451536</td>\n",
              "      <td>-1.694315</td>\n",
              "      <td>0.599396</td>\n",
              "      <td>-0.282867</td>\n",
              "      <td>-1.022077</td>\n",
              "      <td>-0.158629</td>\n",
              "      <td>-0.464418</td>\n",
              "      <td>-0.463202</td>\n",
              "      <td>-0.25204</td>\n",
              "      <td>-0.249464</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>1</th>\n",
              "      <td>-0.067792</td>\n",
              "      <td>0.925753</td>\n",
              "      <td>-0.104067</td>\n",
              "      <td>0.514274</td>\n",
              "      <td>-0.002820</td>\n",
              "      <td>-0.011578</td>\n",
              "      <td>-0.006673</td>\n",
              "      <td>-0.04772</td>\n",
              "      <td>-0.002571</td>\n",
              "      <td>-0.044136</td>\n",
              "      <td>-0.009782</td>\n",
              "      <td>2.39698</td>\n",
              "      <td>-0.005679</td>\n",
              "      <td>-0.010552</td>\n",
              "      <td>-0.004676</td>\n",
              "      <td>-0.00564</td>\n",
              "      <td>-0.011232</td>\n",
              "      <td>-0.009919</td>\n",
              "      <td>-0.027632</td>\n",
              "      <td>0.0</td>\n",
              "      <td>0.0</td>\n",
              "      <td>-0.037263</td>\n",
              "      <td>-1.521417</td>\n",
              "      <td>-1.15664</td>\n",
              "      <td>-0.46409</td>\n",
              "      <td>-0.46352</td>\n",
              "      <td>-0.24796</td>\n",
              "      <td>-0.248631</td>\n",
              "      <td>0.536987</td>\n",
              "      <td>-0.255243</td>\n",
              "      <td>-0.203633</td>\n",
              "      <td>-3.297085</td>\n",
              "      <td>-1.600011</td>\n",
              "      <td>0.599396</td>\n",
              "      <td>-0.282867</td>\n",
              "      <td>-1.146737</td>\n",
              "      <td>-0.158629</td>\n",
              "      <td>-0.464418</td>\n",
              "      <td>-0.463202</td>\n",
              "      <td>-0.25204</td>\n",
              "      <td>-0.249464</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>2</th>\n",
              "      <td>-0.067792</td>\n",
              "      <td>0.925753</td>\n",
              "      <td>-0.104067</td>\n",
              "      <td>0.514274</td>\n",
              "      <td>-0.002824</td>\n",
              "      <td>0.014179</td>\n",
              "      <td>-0.006673</td>\n",
              "      <td>-0.04772</td>\n",
              "      <td>-0.002571</td>\n",
              "      <td>-0.044136</td>\n",
              "      <td>-0.009782</td>\n",
              "      <td>2.39698</td>\n",
              "      <td>-0.005679</td>\n",
              "      <td>-0.010552</td>\n",
              "      <td>-0.004676</td>\n",
              "      <td>-0.00564</td>\n",
              "      <td>-0.011232</td>\n",
              "      <td>-0.009919</td>\n",
              "      <td>-0.027632</td>\n",
              "      <td>0.0</td>\n",
              "      <td>0.0</td>\n",
              "      <td>-0.037263</td>\n",
              "      <td>-1.521417</td>\n",
              "      <td>-1.15664</td>\n",
              "      <td>-0.46409</td>\n",
              "      <td>-0.46352</td>\n",
              "      <td>-0.24796</td>\n",
              "      <td>-0.248631</td>\n",
              "      <td>0.536987</td>\n",
              "      <td>-0.255243</td>\n",
              "      <td>-0.203633</td>\n",
              "      <td>-3.142633</td>\n",
              "      <td>-1.505707</td>\n",
              "      <td>0.599396</td>\n",
              "      <td>-0.282867</td>\n",
              "      <td>-1.188291</td>\n",
              "      <td>-0.158629</td>\n",
              "      <td>-0.464418</td>\n",
              "      <td>-0.463202</td>\n",
              "      <td>-0.25204</td>\n",
              "      <td>-0.249464</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>3</th>\n",
              "      <td>-0.067792</td>\n",
              "      <td>0.925753</td>\n",
              "      <td>-0.104067</td>\n",
              "      <td>0.514274</td>\n",
              "      <td>-0.002840</td>\n",
              "      <td>0.014179</td>\n",
              "      <td>-0.006673</td>\n",
              "      <td>-0.04772</td>\n",
              "      <td>-0.002571</td>\n",
              "      <td>-0.044136</td>\n",
              "      <td>-0.009782</td>\n",
              "      <td>2.39698</td>\n",
              "      <td>-0.005679</td>\n",
              "      <td>-0.010552</td>\n",
              "      <td>-0.004676</td>\n",
              "      <td>-0.00564</td>\n",
              "      <td>-0.011232</td>\n",
              "      <td>-0.009919</td>\n",
              "      <td>-0.027632</td>\n",
              "      <td>0.0</td>\n",
              "      <td>0.0</td>\n",
              "      <td>-0.037263</td>\n",
              "      <td>-1.530800</td>\n",
              "      <td>-1.16476</td>\n",
              "      <td>-0.46409</td>\n",
              "      <td>-0.46352</td>\n",
              "      <td>-0.24796</td>\n",
              "      <td>-0.248631</td>\n",
              "      <td>0.536987</td>\n",
              "      <td>-0.255243</td>\n",
              "      <td>-0.203633</td>\n",
              "      <td>-2.988182</td>\n",
              "      <td>-1.411403</td>\n",
              "      <td>0.599396</td>\n",
              "      <td>-0.282867</td>\n",
              "      <td>-1.188291</td>\n",
              "      <td>-0.158629</td>\n",
              "      <td>-0.464418</td>\n",
              "      <td>-0.463202</td>\n",
              "      <td>-0.25204</td>\n",
              "      <td>-0.249464</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>4</th>\n",
              "      <td>-0.067792</td>\n",
              "      <td>0.925753</td>\n",
              "      <td>-0.104067</td>\n",
              "      <td>0.514274</td>\n",
              "      <td>-0.002842</td>\n",
              "      <td>0.035214</td>\n",
              "      <td>-0.006673</td>\n",
              "      <td>-0.04772</td>\n",
              "      <td>-0.002571</td>\n",
              "      <td>-0.044136</td>\n",
              "      <td>-0.009782</td>\n",
              "      <td>2.39698</td>\n",
              "      <td>-0.005679</td>\n",
              "      <td>-0.010552</td>\n",
              "      <td>-0.004676</td>\n",
              "      <td>-0.00564</td>\n",
              "      <td>-0.011232</td>\n",
              "      <td>-0.009919</td>\n",
              "      <td>-0.027632</td>\n",
              "      <td>0.0</td>\n",
              "      <td>0.0</td>\n",
              "      <td>-0.037263</td>\n",
              "      <td>-1.530800</td>\n",
              "      <td>-1.16476</td>\n",
              "      <td>-0.46409</td>\n",
              "      <td>-0.46352</td>\n",
              "      <td>-0.24796</td>\n",
              "      <td>-0.248631</td>\n",
              "      <td>0.536987</td>\n",
              "      <td>-0.255243</td>\n",
              "      <td>-0.203633</td>\n",
              "      <td>-2.833731</td>\n",
              "      <td>-1.317100</td>\n",
              "      <td>0.599396</td>\n",
              "      <td>-0.282867</td>\n",
              "      <td>-1.209067</td>\n",
              "      <td>-0.158629</td>\n",
              "      <td>-0.464418</td>\n",
              "      <td>-0.463202</td>\n",
              "      <td>-0.25204</td>\n",
              "      <td>-0.249464</td>\n",
              "    </tr>\n",
              "  </tbody>\n",
              "</table>\n",
              "</div>"
            ],
            "text/plain": [
              "   duration  protocol_type  ...  dst_host_rerror_rate  dst_host_srv_rerror_rate\n",
              "0 -0.067792       0.925753  ...              -0.25204                 -0.249464\n",
              "1 -0.067792       0.925753  ...              -0.25204                 -0.249464\n",
              "2 -0.067792       0.925753  ...              -0.25204                 -0.249464\n",
              "3 -0.067792       0.925753  ...              -0.25204                 -0.249464\n",
              "4 -0.067792       0.925753  ...              -0.25204                 -0.249464\n",
              "\n",
              "[5 rows x 41 columns]"
            ]
          },
          "metadata": {
            "tags": []
          },
          "execution_count": 11
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "M6URlefYs9Ji",
        "colab_type": "code",
        "outputId": "575c6ba1-58f5-4f04-fbb1-e0fe1e9dc912",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 86
        }
      },
      "source": [
        "covar_matrix = PCA(n_components = 41)\n",
        "covar_matrix.fit(X)\n",
        "variance = covar_matrix.explained_variance_ratio_ #calculate variance ratios\n",
        "\n",
        "var=np.cumsum(np.round(covar_matrix.explained_variance_ratio_, decimals=3)*100)\n",
        "var #cumulative sum of variance explained with [n] features"
      ],
      "execution_count": 0,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "array([26. , 37.9, 46.9, 54.5, 59.2, 63.3, 66.4, 69.3, 72.2, 74.8, 77.4,\n",
              "       79.9, 82.4, 84.8, 87. , 89.2, 91.2, 93.1, 94.9, 95.9, 96.8, 97.7,\n",
              "       98.3, 98.8, 99.2, 99.5, 99.6, 99.7, 99.8, 99.9, 99.9, 99.9, 99.9,\n",
              "       99.9, 99.9, 99.9, 99.9, 99.9, 99.9, 99.9, 99.9])"
            ]
          },
          "metadata": {
            "tags": []
          },
          "execution_count": 12
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "rIEsq9aCtWEl",
        "colab_type": "code",
        "outputId": "e4bb1fa6-2901-4db5-a41f-43a50273f3ab",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 312
        }
      },
      "source": [
        "plt.ylabel('% Variance Explained')\n",
        "plt.xlabel('# of Features')\n",
        "plt.title('PCA Analysis')\n",
        "plt.ylim(20,100.5)\n",
        "plt.style.context('seaborn-whitegrid')\n",
        "\n",
        "\n",
        "plt.plot(var)"
      ],
      "execution_count": 0,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "[<matplotlib.lines.Line2D at 0x7fbfcc508cc0>]"
            ]
          },
          "metadata": {
            "tags": []
          },
          "execution_count": 13
        },
        {
          "output_type": "display_data",
          "data": {
            "image/png": "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\n0/8HO8OkJXHLeHQAAAAASUVORK5CYII=\n",
            "text/plain": [
              "<Figure size 432x288 with 1 Axes>"
            ]
          },
          "metadata": {
            "tags": []
          }
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "-0S7muQJ5L4R",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        ""
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "uohEKlDceJtS",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        ""
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "tQCadc-j5MWG",
        "colab_type": "text"
      },
      "source": [
        "##Training "
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "c0Vrlhhp3i1J",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "df_train = pd.read_csv(\"/content/gdrive/My Drive/data/df_train.csv\")\n",
        "df_val = pd.read_csv(\"/content/gdrive/My Drive/data/df_val.csv\")"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "UFXLESNSOsHP",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "# A utility method to create a tf.data dataset from a Pandas Dataframe\n",
        "def df_to_dataset(dataframe, shuffle=True, batch_size=32):\n",
        "  dataframe = dataframe.copy()\n",
        "  labels = dataframe.pop('label')\n",
        "  ds = tf.data.Dataset.from_tensor_slices((dict(dataframe), labels))\n",
        "  if shuffle:\n",
        "    ds = ds.shuffle(buffer_size=len(dataframe))\n",
        "  ds = ds.batch(batch_size)\n",
        "  return ds"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "uV3S2Ywbq6Mr",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "# train, test = train_test_split(df, test_size=0.2)\n",
        "# train, val = train_test_split(train, test_size=0.2)\n",
        "# print(len(train), 'train examples')\n",
        "# print(len(val), 'validation examples')\n",
        "# print(len(test), 'test examples')\n",
        "\n",
        "# batch size is a hyperparameter that defines the number of samples to work\n",
        "# Adjust the batch_size as per the RAM availability before modeling.\n",
        "batch_size = 5000\n",
        "\n",
        "# creating the tf.data dataset\n",
        "train_ds = df_to_dataset(df_train, batch_size=batch_size)\n",
        "val_ds = df_to_dataset(df_val, shuffle=False, batch_size=batch_size)\n",
        "\n"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "eTUjgq25q6Qz",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "# Generating feature layer for keras sequential model.\n",
        "feature_columns = []\n",
        "for header in list(df.columns)[:-1]:\n",
        "  feature_columns.append(feature_column.numeric_column(header))\n",
        "feature_layer = tf.keras.layers.DenseFeatures(feature_columns)"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "z4oChvXgq6Us",
        "colab_type": "code",
        "outputId": "dd62f0b7-dc06-4c05-973d-fbd6fa79893c",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 280
        }
      },
      "source": [
        "# Create, compile, and train the model\n",
        "model = tf.keras.Sequential([\n",
        "  feature_layer,\n",
        "  layers.Dense(128, activation='relu'),\n",
        "  layers.Dense(5, activation='softmax')\n",
        "])\n",
        "\n",
        "model.compile(optimizer='adamax',\n",
        "              loss='sparse_categorical_crossentropy',\n",
        "              metrics=['accuracy'])\n",
        "\n",
        "# model.fit(train_ds,\n",
        "#           validation_data=val_ds,\n",
        "#           epochs=5,\n",
        "#           callbacks=[TensorBoardColabCallback(tbc)])\n",
        "\n",
        "history = model.fit(train_ds,\n",
        "          validation_data=val_ds,\n",
        "          epochs=5,workers=10\n",
        "          )"
      ],
      "execution_count": 9,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "WARNING:tensorflow:From /usr/local/lib/python3.6/dist-packages/tensorflow_core/python/ops/resource_variable_ops.py:1630: calling BaseResourceVariable.__init__ (from tensorflow.python.ops.resource_variable_ops) with constraint is deprecated and will be removed in a future version.\n",
            "Instructions for updating:\n",
            "If using Keras pass *_constraint arguments to layers.\n",
            "Train on 490 steps, validate on 245 steps\n",
            "Epoch 1/5\n",
            "490/490 [==============================] - 192s 391ms/step - loss: 14.0953 - acc: 0.9838 - val_loss: 194.6423 - val_acc: 0.9958\n",
            "Epoch 2/5\n",
            "490/490 [==============================] - 216s 440ms/step - loss: 1.9927 - acc: 0.9951 - val_loss: 184.6128 - val_acc: 0.9942\n",
            "Epoch 3/5\n",
            "490/490 [==============================] - 217s 444ms/step - loss: 1.0450 - acc: 0.9964 - val_loss: 171.0138 - val_acc: 0.9982\n",
            "Epoch 4/5\n",
            "490/490 [==============================] - 231s 472ms/step - loss: 1.2415 - acc: 0.9977 - val_loss: 159.5977 - val_acc: 0.9987\n",
            "Epoch 5/5\n",
            "490/490 [==============================] - 223s 455ms/step - loss: 3.0416 - acc: 0.9970 - val_loss: 160.2755 - val_acc: 0.9973\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "t2-qDnpgI7W3",
        "colab_type": "code",
        "outputId": "7264c89d-2b9b-4b74-de42-5a8f61e3263d",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 573
        }
      },
      "source": [
        "import matplotlib.pyplot as plt\n",
        "\n",
        "# Plot training & validation accuracy values\n",
        "plt.plot(history.history['acc'])\n",
        "plt.plot(history.history['val_acc'])\n",
        "plt.title('Model accuracy')\n",
        "plt.ylabel('Accuracy')\n",
        "plt.xlabel('Epoch')\n",
        "plt.legend(['Train', 'Validation'], loc='best')\n",
        "plt.show()\n",
        "\n",
        "# Plot training & validation loss values\n",
        "plt.plot(history.history['loss'])\n",
        "plt.plot(history.history['val_loss'])\n",
        "plt.title('Model loss')\n",
        "plt.ylabel('Loss')\n",
        "plt.xlabel('Epoch')\n",
        "plt.legend(['Train', 'Validation'], loc='best')\n",
        "plt.show()\n",
        "\n"
      ],
      "execution_count": 10,
      "outputs": [
        {
          "output_type": "display_data",
          "data": {
            "image/png": "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\n",
            "text/plain": [
              "<Figure size 432x288 with 1 Axes>"
            ]
          },
          "metadata": {
            "tags": []
          }
        },
        {
          "output_type": "display_data",
          "data": {
            "image/png": "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\n",
            "text/plain": [
              "<Figure size 432x288 with 1 Axes>"
            ]
          },
          "metadata": {
            "tags": []
          }
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "1WpY6crTmxrv",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "df_test = pd.read_csv(\"/content/gdrive/My Drive/data/df_test.csv\")"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "d90NgHFZfRzW",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "test_ds = df_to_dataset(df_test, shuffle=False, batch_size=batch_size)"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "gdKM5YdarNxc",
        "colab_type": "code",
        "outputId": "47ba5756-c959-41c0-be86-51e2bb803a20",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 52
        }
      },
      "source": [
        "# Testing on the heldout dataset from training samples.\n",
        "loss, accuracy = model.evaluate(test_ds)\n",
        "print(\"Accuracy on heldout test dataset: \", accuracy)\n"
      ],
      "execution_count": 13,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "245/245 [==============================] - 49s 199ms/step - loss: 39.7030 - acc: 0.9973\n",
            "Accuracy on heldout test dataset:  0.9972718\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "QyN73k7KCzn0",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "y_true = df_test.iloc[:,-1].astype('int')\n",
        "y_pred = model.predict(test_ds)"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "b1GKhgOTCuDx",
        "colab_type": "code",
        "outputId": "607eca3a-11a0-4381-cfb9-37b33b236ef4",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 104
        }
      },
      "source": [
        "confusion_matrix(y_true, y_pred.argmax(axis=1))"
      ],
      "execution_count": 15,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "array([[241583,     61,   1548,      2,      1],\n",
              "       [   797, 970004,     42,      0,      0],\n",
              "       [   330,    272,   9667,      7,      0],\n",
              "       [   252,      0,     16,     13,      0],\n",
              "       [    13,      0,      0,      0,      0]])"
            ]
          },
          "metadata": {
            "tags": []
          },
          "execution_count": 15
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "-SdAIQ3VEdVu",
        "colab_type": "code",
        "outputId": "94ecbea0-8d78-4e48-ef15-3a9258707d9c",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 225
        }
      },
      "source": [
        "print(classification_report(y_true, y_pred.argmax(axis=1)))"
      ],
      "execution_count": 16,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "              precision    recall  f1-score   support\n",
            "\n",
            "           0       0.99      0.99      0.99    243195\n",
            "           1       1.00      1.00      1.00    970843\n",
            "           2       0.86      0.94      0.90     10276\n",
            "           3       0.59      0.05      0.09       281\n",
            "           4       0.00      0.00      0.00        13\n",
            "\n",
            "    accuracy                           1.00   1224608\n",
            "   macro avg       0.69      0.60      0.60   1224608\n",
            "weighted avg       1.00      1.00      1.00   1224608\n",
            "\n"
          ],
          "name": "stdout"
        }
      ]
    }
  ]
}